package com.yiqixuejava.reconciliation.JDBC;

import com.yiqixuejava.reconciliation.dto.RDetail;
import com.yiqixuejava.reconciliation.entity.SourceEntity;
import com.yiqixuejava.reconciliation.exception.ServiceException;
import com.yiqixuejava.reconciliation.service.ReconService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.LinkedList;
import java.util.List;

import static com.yiqixuejava.reconciliation.exception.CoreExceptionEnum.*;
@Service(value = "Alipy")
@Scope("prototype")
public class JDBCService implements ReconService,Runnable{
    static Connection connection;
    static PreparedStatement preparedStatement;
    static ResultSet resultSet;
    SourceEntity sourceEntity;
    static int limit_Number=1000;
    static int page = 1;
    /**
     * 对账准备接口，实现方应该准备好对账所需资源
     * @throws ServiceException
     */
    public void prepare(SourceEntity sourceEntity) throws ServiceException{
        try{
            String url = sourceEntity.getUri();
            String username = sourceEntity.getParam1();
            String driver = sourceEntity.getParam3();
            String password = sourceEntity.getParam2();
            Class.forName(driver);
            connection = DriverManager.getConnection(url,username,password);
            this.page = 1;
        }catch (Exception e){
            throw new ServiceException(Error_Connection);
        }
    }

    /**
     * 获取对账数据
     * @return
     */
    public List<RDetail> getNextData(int maxSize){
        //查询所需数据
       List rDetailList = getData(maxSize);
        return rDetailList;
    }


    /**
     * 关闭资源接口，如关闭流或者数据库连接
     */
    public void destroy(){
        Close(connection,preparedStatement,resultSet);
    }

    /**
     * 查询数据
     * @param second
     * @return
     */
    public static List<RDetail> SelectAll(int second,int limit_Number,List<RDetail> rDetailList){
        try{
            String sql = "select out_trade_no,total_amount,bill_finish_time from b_collect_alipay where save_time between '2018-08-01 00:00:00' and '2018-08-04 00:00:00' limit ?,?";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,(second-1)*limit_Number);
            preparedStatement.setInt(2,limit_Number);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                RDetail rDetail=new RDetail();
                rDetail.setOrderNo(resultSet.getString("out_trade_no"));
                rDetail.setTradeAmount(resultSet.getString("total_amount") == null ? "0.00" : resultSet.getString("total_amount"));
                rDetail.setTradeDateTime(resultSet.getString("bill_finish_time"));
                rDetailList.add(rDetail);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return rDetailList;
    }


    /**
     * 查询数据总数
     */
    public static int SelectCount(){
        int count=0;
        try{
            String sql = "select count(*) from b_collect_alipay where save_time between '2018-08-01 00:00:00' and '2018-08-04 00:00:00'";
            preparedStatement = connection.prepareStatement(sql);
            resultSet=preparedStatement.executeQuery();
            while (resultSet.next()){
                count=resultSet.getInt(1);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 获取所有数据
     * @param maxSize
     * @return
     */

    public static List<RDetail> getData(int maxSize){
        List<RDetail> rDetailList = new LinkedList<RDetail>();
        int slectcount=SelectCount();
        //maxSize为负数
        if(0 >= maxSize){
            throw new ServiceException(Result_Is_Negative);
        }
        //maxSize小于限制limit_Number
        if(Compare(maxSize,limit_Number) == false){
            System.out.println("maxSize小于限制limit_Number");
            try{
                if(slectcount>0 ){
                    int limit = maxSize;
                    SelectAll(1,limit,rDetailList);
                }
            }catch (Exception e){
                throw new ServiceException(Not_Data);
            }
        }
        //maxSize大于限制limit_Number
        if(Compare(maxSize,limit_Number) == true){
            System.out.println("maxSize大于限制limit_Number");
            try{
                if(slectcount > 0){
                    int second=1;
                    while (second<=(maxSize/limit_Number)){
                        rDetailList = SelectAll(page,limit_Number,rDetailList);
                        second++;
                        page++;
                        if(rDetailList.size() < limit_Number){
                            break;
                        }
                    }
                    if((maxSize%limit_Number)>0){
                        System.out.println(second);
                        rDetailList = SelectAll(second,maxSize%limit_Number,rDetailList);
                    }
                }
            }catch (Exception e){
                throw new ServiceException(Not_Data);
            }
        }
        return rDetailList;
    }
    /**
     * 比较
     * @param maxsize
     * @param limit_Number
     * @return
     */
    public static boolean Compare(int maxsize,int limit_Number){
        if(limit_Number > maxsize){
            return false;
        }
        return true;
    }
    /**
     * 关闭资源连接
     * @param connection
     * @param preparedStatement
     * @param resultSet
     */
    public static void Close(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
        try{
            resultSet.close();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            try {
                preparedStatement.close();
            }catch (SQLException e){
                e.printStackTrace();
            }finally {
                try{
                    connection.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
    ThreadLocal<Integer> threadLocal=new ThreadLocal<Integer>(){
        @Override
        protected Integer initialValue() {
            return page=1;
        }
    };
    @Override
    public void run() {
        if(threadLocal.get()==1){
            page=threadLocal.get();
        }
    }
}
